﻿package net.roading.net
{
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	//
	import flash.events.EventDispatcher;
    import flash.events.Event;
	//
	import net.roading.events.SoapEvent;
	//
	/*WebService*/
	public class WebService 
	{
		private var wsUrl:String;
		private var wsdlLoaded:Boolean = false;
		//
		private var waitCallMethods:Array = [];
		//
		private var wsNsName:String;
		private var methods:Object = {};
		//
		public var onError:Function;
		public var onLoad:Function;
		//	
		public function WebService(url:String) 
		{
			//判断后面有没有?wsdl
			if(url.substr(-4,4).toLowerCase()=="wsdl")
			{ 
				url = url.substr(0,url.length-5);
			}
			wsUrl = url;
			//
			loadWsdl();
		}
		//获取ws的函数列表信息
		public function getWsInfo()
		{
			if(wsdlLoaded)
			{
				var str:String = "/*********************************************************/";
				str+="\nwebservice的方法列表如下:\n";
				for(var i in methods)
				{
					str+="\tmethod name: "+i;
					if(methods[i].length > 0)
					{
						str+="\targs: {";
						for(var j=0;j<methods[i].length;j++)
						{
							str+="(name:"+methods[i][j].name+","+"type:'"+methods[i][j].type+"') "
						}
						str+="}\n";
					}
					else
					{
						str+="\n";
					}
				}
				str += "/*********************************************************/";
				return str;
			}
			else
			{
				return "wsdl not loaded";
			}
		}
		//公开调用接口
		public function call(command:String, ... arguments):EventDispatcher 
		{
			var response:EventDispatcher = new EventDispatcher();
			if(wsdlLoaded)
			{
				loadWebService(command,response,arguments);
			}
			else
			{
				waitCallMethods.push({cmd:command,arg:arguments,res:response});
			}
			return response;
		}
		//调用
		private function loadWebService(command:String, response:EventDispatcher,arguments):void 
		{
			if(methods[command] != null)
			{
				if(methods[command].length != arguments.length)
					trace("Warning: 参数长度不匹配!");
				//
				new SoapCaller(wsUrl, wsNsName, methods[command], command, response, arguments);
			}
			else
			{
				response.dispatchEvent(new SoapEvent("error", {target:this, level:"WebService.Call.MethodNameNotFound",code:"找不到调用方法"}));
			}
		}
		//调用等待列表
		private function loadWaitCallMethods():void
		{
			for(var i in waitCallMethods)
			{
				var o= waitCallMethods[i];
				loadWebService(o.cmd,o.res,o.arg);
			}
			waitCallMethods = [];
		}
		//{wsdl 加载和分析wsdl
		private function loadWsdl():void
		{
			var urlLoader:URLLoader = new URLLoader();
			//
			var urlRequest:URLRequest = new URLRequest();
			urlRequest.url = wsUrl + "?wsdl";
			urlRequest.method = URLRequestMethod.POST;
			urlLoader.addEventListener("complete", completeHandler);
			urlLoader.addEventListener("ioError", ioerrorHandler);
			urlLoader.load(urlRequest);
		}
		private function completeHandler(e:Event):void
		{
			wsdlLoaded = true;
			//
			var tmpXML:XML, dNs:Namespace, sNs:Namespace, elementXML:*;
			//
			tmpXML = XML(e.target.data);
			dNs = tmpXML.namespace();
			sNs = tmpXML.namespace("s");
			//
			elementXML = tmpXML.dNs::["types"].sNs::["schema"];
			wsNsName = elementXML.@targetNamespace;
			//
			var nodes = elementXML.sNs::element;
			for (var i =0; i<nodes.length(); i+=2) {
				var nodeName:String = nodes[i].@name;
				methods[nodeName] = [];
				//
				for (var j =0; j<nodes[i].sNs::complexType.sNs::sequence.sNs::element.length(); j++)
				{
					var n = nodes[i].sNs::complexType.sNs::sequence.sNs::element[j];
					methods[nodeName].push({name:n.@name,type:n.@type});
				}
			}
			//
			if(onLoad!=null)onLoad(e);
			//-------------------------------
			loadWaitCallMethods();
		}
		
		private function ioerrorHandler(e:Event):void
		{
			trace("load wsdl error!");
			if(onError!=null)onError(e);
		}
		//}
	}
}